[Chapter 14] Headers, Precedence, and Trust
Author: Bryan Costales & Eric Allman
Date: 1999-01-06T18:38:22Z

#

| Chapter 14 |

# 14. Headers, Precedence, and Trust

Contents:
Headers
Headers Versus Delivery Agent Flags
Headers Learned So Far
Precedence
Sending Real Mail
Trusted User
Things to Try

In the previous chapter you sent mail to yourself and saw that sendmail added several problematic header lines to your message. Also the hub machine added some unsuitable headers. In this chapter we show how to use the `H` configuration command to add legal headers to a message, the `P` configuration command to set message priorities, and the `T` configuration command to define "trusted" users.

## 14.1 Headers

The header configuration command begins with the letter `H`. Like all configuration commands, the `H` is the first character on a line. The `H` is then followed by the name of a header:

>     Hname: field

Here, `name` is the name of a header, such as `Subject`. The list of all header names that are of interest to sendmail can be found in Chapter 35, Headers. The name is followed by a colon and then text that is appropriate for the header. Optional whitespace can surround the colon.

RFC822 (modified by RFC1123) specifies that certain header lines must appear in all email messages. Of those, the two you will first add to the client.cf file are shown in Table 14.1.

Table 14.1: Two Required Headers
Name | Description | When Added
--- | --- | ---
`From:` | Address of the sender | If missing
`Received:` | Record of receipt | Always

Unless otherwise specified (as you will see later), a header that is declared in the configuration file is added to a mail message only if one doesn't already exist. The exception to this rule is the `Received:` header. It is always added to a mail message, even if there is already one (or more) there.

### 14.1.1 The From: Header

The `From:` header contains the official address of the sender. Declaring the `From:` header is simplicity itself, because it uses as its `field` a single macro surrounded by angle braces:

>     HFrom: <$g>

Recall that there are two kinds of macros: those that you define with the `D` command and those that sendmail defines. The `g` macro is one of the latter. The value sendmail gives the `g` macro is the address of the sender (generated by sendmail) as it appears on the envelope. That address, when you are the sender, was generated by the `Hubset` rule set:

>     SHubset # Rewrite the sender for the hub
>     R$-             $@ $1@${HUB}            user -> user@hub

The sender address (you) is rewritten by this rule so that it becomes you@mail.us.edu. That is, the hostname and domain of the hub machine are appended so that the mail appears to come from the hub. This is the envelope address of the sender, and that is the address placed into the `g` macro. For email sent by you, the value that is given to `$g` (and thus to the `From:` header) is:

>     From: <you@mail.us.edu>

The `From:` header is added to an outgoing mail message only if there is not already a `From:` header there. (Often an MUA will add a `From:` header.) It is placed into the client.cf file to ensure that no mail leaves the local machine without this required header.

### 14.1.2 The Received: Header

The `Received:` header is special. It is always added to the header portion of every mail message, even if one or more of them are already present.

The `Received:` header is used to make a record of each machine that mail has passed through. When sendmail calculates a hop count (to bounce mail with too many hops), it does so by counting the `Received:` header lines. The declaration of the `Received:` header is a bit complicated. A minimal `Received:` header declaration looks like this:

>     HReceived: by $j; $b

The word `by` is mandatory. It must be followed by the fully qualified, official name of the local machine. As you saw earlier when you ran sendmail with the `-d0.1` debugging switch, the fully qualified name was assigned to the `j` macro:

>     ============ SYSTEM IDENTITY (after readcf) ============
>           (short domain name) $w = here
>       (canonical domain name) $j = here.us.edu

>                             note

The `Received:` header definition concludes with a semicolon, followed by the current date and time as stored in `$b`. The `b` macro contains the current date in ARPAnet format; that is, the day of the week, the month, the day, the time, the year, and the time zone.

These items in the `Received:` header form the minimum information required in this header.

### 14.1.3 Testing So Far

Add the `From:` and `Received:` headers to the client.cf file. The new lines in client.cf will look like this:

>     O OldStyleHeaders=True
>     O BlankSub=.                    # Replace unquoted spaces with a dot.

>     # Headers                                                               new
>     HFrom: <$g>                     # Added only if missing                 new
>     HReceived: by $j; $b            # Always added                          new

Here, they follow the options that were added in the last chapter. As usual, comments have been included to clarify your intent. See Chapter 31, Defined Macros, for a more detailed explanation of the `j` and `b` macros.

Now send mail to yourself just as you did at the end of the preceding chapter:

>     % ./sendmail -Cclient.cf you
>     Subject: testing
>     To: you

>     testing
>     .

Retrieve the mail that you just sent, save it to a file, and look at what you saved. It will look something like this:

>     From you@mail.us.edu Fri Dec 13 05:47:47 1996
>     Return-Path: <you@mail.us.edu>
>     Received: from here.us.edu (you@here.us.edu [123.45.67.8]) by
>     mail.us.edu
>     (8.8.4/8.8.4) with ESMTP id FAA13451 for <you>; Fri, 13 Dec 1996 05:47:46 -0700
>     Date: Fri, 13 Dec 1996 05:47:46 -0700
>     From: you@mail.us.edu (Your Full Name)                                   note
>     Message-Id: <199509091247.FAA13451@mail.us.edu>
>     Received: by here.us.edu; Fri, 13 Dec 1996 05:47:44 -0700                note
>     Subject: testing
>     To: you

>     testing

Notice that a new `Received:` header was added. This is the one just declared in the client.cf file. The two `Received:` headers form a trail that shows who first received the message and how it was passed from one machine to the other.

Also notice that the contents of the `From:` header have changed. Something has removed the angle brackets and added your full name. What happened was this:

1. On the hub machine the address in the envelope for the sender is taken from the RCPT message that the local machine sends during the SMTP conversation. That address is the value of `$g` with angle brackets added.

2. On the hub machine the address in the `From:` header is compared to the sender envelope address. The address in the `From:` header that client.cf supplied was the value of `$g` surrounded in angle brackets.

3. Whenever the address in the envelope for the sender and the address in the `From:` header are identical, sendmail removes the `From:` header and creates a new one. Thus sendmail on a correctly configured hub machine removes the `From:` header and creates a new one that includes your full name.

The definition of the `From:` header on a hub is more complex then that in the client.cf file. One possible definition might look like this:

>     From: $g $?x($x)$.

This is just like the local definition, but it has a macro conditional added. A macro conditional is simply an if-endif construction, where `$?` is the if and `$.` is the endif. The preceding definition, then, can be broken down like this:

>     $?        if
>     x             the macro x contains a value
>     ($x)            add this to the definition
>     $.        endif

The macro `x` contains as its value the full name of the sender. If that full name is not known, `x` has no value and the full name is omitted. If `$x` does contain a value, the full name is added in parentheses. Macro conditionals are described in Chapter 31.

13.5 Things to Try |  | 14.2 Headers Versus Delivery Agent Flags